package org.jeecg.modules.system.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.PermissionData;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.entity.*;
import org.jeecg.modules.system.service.*;
import org.jeecg.modules.system.service.ISysUserRoleService;
import org.jeecg.modules.system.service.ISysRolePermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.jeecg.modules.base.service.BaseCommonService;
import io.swagger.annotations.ApiOperation;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 租户配置信息
 * @author: jeecg-boot
 */
@Slf4j
@RestController
@RequestMapping("/sys/tenant")
public class SysTenantController {

    @Autowired
    private ISysTenantService sysTenantService;
    
    @Autowired
    private ISysUserService sysUserService;
    
    @Autowired
    private ISysRoleService sysRoleService;
    
    @Autowired
    private ISysPermissionService sysPermissionService;
    
    @Autowired
    private ISysUserRoleService sysUserRoleService;
    
    @Autowired
    private ISysRolePermissionService sysRolePermissionService;

    @Autowired
    private BaseCommonService baseCommonService;

    /**
     * 获取列表数据
     * @param sysTenant
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @PermissionData(pageComponent = "system/TenantList")
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public Result<IPage<SysTenant>> queryPageList(SysTenant sysTenant,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
									  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
		Result<IPage<SysTenant>> result = new Result<IPage<SysTenant>>();
        //---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询---
        Date beginDate=null;
        Date endDate=null;
        if(oConvertUtils.isNotEmpty(sysTenant)) {
            beginDate=sysTenant.getBeginDate();
            endDate=sysTenant.getEndDate();
            sysTenant.setBeginDate(null);
            sysTenant.setEndDate(null);
        }
        //---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询---
        QueryWrapper<SysTenant> queryWrapper = QueryGenerator.initQueryWrapper(sysTenant, req.getParameterMap());
        //---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询---
        if(oConvertUtils.isNotEmpty(sysTenant)){
            queryWrapper.ge(oConvertUtils.isNotEmpty(beginDate),"begin_date",beginDate);
            queryWrapper.le(oConvertUtils.isNotEmpty(endDate),"end_date",endDate);
        }
        //---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询---
		Page<SysTenant> page = new Page<SysTenant>(pageNo, pageSize);
		IPage<SysTenant> pageList = sysTenantService.page(page, queryWrapper);
		result.setSuccess(true);
		result.setResult(pageList);
		return result;
	}

    /**
     *   添加
     * @param
     * @return
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public Result<SysTenant> add(@RequestBody SysTenant sysTenant) {
        Result<SysTenant> result = new Result();
        try {
            // 检查租户编号是否已存在
            if (sysTenant.getId() == null) {
                // 如果没有提供ID，自动生成
                QueryWrapper<SysTenant> queryWrapper = new QueryWrapper<>();
                queryWrapper.orderByDesc("id");
                queryWrapper.last("limit 1");
                SysTenant maxTenant = sysTenantService.getOne(queryWrapper);
                Integer nextId = maxTenant != null ? maxTenant.getId() + 1 : 1;
                sysTenant.setId(nextId);
            } else if (sysTenantService.getById(sysTenant.getId()) != null) {
                // 如果提供的ID已存在
                return result.error500("该租户编号已存在!");
            }
            
            sysTenantService.save(sysTenant);
            result.success("添加成功！");
        } catch (Exception e) {
            log.error("添加租户失败", e);
            result.error500("操作失败: " + e.getMessage());
        }
        return result;
    }

    /**
     *  编辑
     * @param
     * @return
     */
    @RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST})
    public Result<SysTenant> edit(@RequestBody SysTenant tenant) {
        Result<SysTenant> result = new Result();
        SysTenant sysTenant = sysTenantService.getById(tenant.getId());
        if(sysTenant==null) {
           return result.error500("未找到对应实体");
        }
        boolean ok = sysTenantService.updateById(tenant);
        if(ok) {
            result.success("修改成功!");
        }
        return result;
    }

    /**
     *   通过id删除
     * @param id
     * @return
     */
    @RequestMapping(value = "/delete", method ={RequestMethod.DELETE, RequestMethod.POST})
    public Result<?> delete(@RequestParam(name="id",required=true) String id) {
        sysTenantService.removeTenantById(id);
        return Result.ok("删除成功");
    }

    /**
     *  批量删除
     * @param ids
     * @return
     */
    @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
    public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
        Result<?> result = new Result<>();
        if(oConvertUtils.isEmpty(ids)) {
            result.error500("未选中租户！");
        }else {
            String[] ls = ids.split(",");
            // 过滤掉已被引用的租户
            List<Integer> idList = new ArrayList<>();
            for (String id : ls) {
                Long userCount = sysTenantService.countUserLinkTenant(id);
                if (userCount == 0) {
                    idList.add(Integer.parseInt(id));
                }
            }
            if (idList.size() > 0) {
                sysTenantService.removeByIds(idList);
                if (ls.length == idList.size()) {
                    result.success("删除成功！");
                } else {
                    result.success("部分删除成功！（被引用的租户无法删除）");
                }
            }else  {
                result.error500("选择的租户都已被引用，无法删除！");
            }
        }
        return result;
    }

    /**
     * 通过id查询
     * @param id
     * @return
     */
    @RequestMapping(value = "/queryById", method = RequestMethod.GET)
    public Result<SysTenant> queryById(@RequestParam(name="id",required=true) String id) {
        Result<SysTenant> result = new Result<SysTenant>();
        SysTenant sysTenant = sysTenantService.getById(id);
        if(sysTenant==null) {
            result.error500("未找到对应实体");
        }else {
            result.setResult(sysTenant);
            result.setSuccess(true);
        }
        return result;
    }
    
    /**
     * 检查租户编号是否存在
     * @param id
     * @return
     */
    @RequestMapping(value = "/checkIdExist", method = RequestMethod.GET)
    public Result<Boolean> checkIdExist(@RequestParam(name="id",required=true) Integer id) {
        Result<Boolean> result = new Result<>();
        try {
            if (id == null) {
                result.setSuccess(false);
                result.setMessage("租户编号不能为空");
                return result;
            }
            
            SysTenant sysTenant = sysTenantService.getById(id);
            if(sysTenant != null) {
                result.setResult(true);
                result.setMessage("租户编号已存在");
            } else {
                result.setResult(false);
                result.setMessage("租户编号可用");
            }
            result.setSuccess(true);
        } catch (Exception e) {
            log.error("检查租户编号是否存在出错", e);
            result.setSuccess(false);
            result.setMessage("检查租户编号出错");
        }
        return result;
    }

    /**
     * 查询有效的 租户数据
     * @return
     */
    @RequestMapping(value = "/queryList", method = RequestMethod.GET)
    public Result<List<SysTenant>> queryList(@RequestParam(name="ids",required=false) String ids) {
        Result<List<SysTenant>> result = new Result<List<SysTenant>>();
        LambdaQueryWrapper<SysTenant> query = new LambdaQueryWrapper<>();
        query.eq(SysTenant::getStatus, 1);
        if(oConvertUtils.isNotEmpty(ids)){
            query.in(SysTenant::getId, ids.split(","));
        }
        //此处查询忽略时间条件
        List<SysTenant> ls = sysTenantService.list(query);
        result.setSuccess(true);
        result.setResult(ls);
        return result;
    }
    /**
     *  查询当前用户的所有有效租户 【当前用于vue3版本】
     * @return
     */
    @RequestMapping(value = "/getCurrentUserTenant", method = RequestMethod.GET)
    public Result<Map<String,Object>> getCurrentUserTenant() {
        Result<Map<String,Object>> result = new Result<Map<String,Object>>();
        try {
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String tenantIds = sysUser.getRelTenantIds();
            Map<String,Object> map = new HashMap(5);
            if (oConvertUtils.isNotEmpty(tenantIds)) {
                List<Integer> tenantIdList = new ArrayList<>();
                for(String id: tenantIds.split(SymbolConstant.COMMA)){
                    tenantIdList.add(Integer.valueOf(id));
                }
                // 该方法仅查询有效的租户，如果返回0个就说明所有的租户均无效。
                List<SysTenant> tenantList = sysTenantService.queryEffectiveTenant(tenantIdList);
                map.put("list", tenantList);
            }
            result.setSuccess(true);
            result.setResult(map);
        }catch(Exception e) {
            log.error(e.getMessage(), e);
            result.error500("查询失败！");
        }
        return result;
    }

    /**
     * 创建租户管理员
     *
     * @param params 管理员信息
     * @return
     */
    @ApiOperation("创建租户管理员")
    @RequestMapping(value = "/createTenantAdmin", method = RequestMethod.POST)
    @Transactional(rollbackFor = Exception.class)
    public Result<String> createTenantAdmin(@RequestBody JSONObject params) {
        Result<String> result = new Result<>();
        try {
            // 获取参数
            String username = params.getString("username");
            String password = params.getString("password");
            String realname = params.getString("realname");
            String phone = params.getString("phone");
            String email = params.getString("email");
            Integer tenantId = params.getInteger("tenantId");
            String roleName = params.getString("roleName");
            String roleCode = params.getString("roleCode");
            JSONArray selectedPermissions = params.getJSONArray("selectedPermissions");
            
            log.info("创建租户管理员，租户ID：{}，用户名：{}", tenantId, username);
            
            // 参数验证
            if (oConvertUtils.isEmpty(username) || oConvertUtils.isEmpty(password) || 
                oConvertUtils.isEmpty(realname) || tenantId == null) {
                return result.error500("必填参数不能为空");
            }
            
            // 用户名格式验证
            if (!username.matches("^[a-zA-Z0-9_]{5,}$")) {
                return result.error500("用户名不符合规则，请输入字母、数字、下划线且不少于5位");
            }
            
            // 密码强度验证
            if (password.length() < 6) {
                return result.error500("密码长度不能小于6位");
            }
            
            // 检查租户是否存在
            SysTenant tenant = sysTenantService.getById(tenantId);
            if (tenant == null) {
                return result.error500("租户不存在");
            }
            
            // 检查用户名是否已存在
            SysUser userCheck = sysUserService.getUserByName(username);
            if (userCheck != null) {
                return result.error500("用户名已存在");
            }
            
            // 检查手机号是否已存在
            if (oConvertUtils.isNotEmpty(phone)) {
                LambdaQueryWrapper<SysUser> phoneQuery = new LambdaQueryWrapper<>();
                phoneQuery.eq(SysUser::getPhone, phone);
                long phoneCount = sysUserService.count(phoneQuery);
                if (phoneCount > 0) {
                    return result.error500("手机号已被注册");
                }
            }
            
            // 检查邮箱是否已存在
            if (oConvertUtils.isNotEmpty(email)) {
                LambdaQueryWrapper<SysUser> emailQuery = new LambdaQueryWrapper<>();
                emailQuery.eq(SysUser::getEmail, email);
                long emailCount = sysUserService.count(emailQuery);
                if (emailCount > 0) {
                    return result.error500("邮箱已被注册");
                }
            }
            
            // 检查该租户是否已有管理员
            // 查询用户表中是否已存在该租户的管理员
            QueryWrapper<SysUser> userQuery = new QueryWrapper<>();
            userQuery.eq("rel_tenant_ids", tenantId.toString());
            List<SysUser> tenantUsers = sysUserService.list(userQuery);
            
            if (tenantUsers != null && !tenantUsers.isEmpty()) {
                // 获取这些用户ID
                List<String> userIds = tenantUsers.stream().map(SysUser::getId).collect(Collectors.toList());
                
                if (userIds != null && !userIds.isEmpty()) {
                    // 查询这些用户是否有人拥有租户管理员角色
                    QueryWrapper<SysUserRole> userRoleQuery = new QueryWrapper<>();
                    userRoleQuery.in("user_id", userIds);
                    List<SysUserRole> userRoles = sysUserRoleService.list(userRoleQuery);
                    
                    if (userRoles != null && !userRoles.isEmpty()) {
                        List<String> roleIds = userRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
                        
                        QueryWrapper<SysRole> roleQuery = new QueryWrapper<>();
                        roleQuery.in("id", roleIds);
                        roleQuery.eq("role_code", "tenant_admin");
                        Long count = sysRoleService.count(roleQuery);
                        
                        if (count > 0) {
                            return result.error500("该租户已有管理员，不能重复创建");
                        }
                    }
                }
            }
            
            // 创建用户
            SysUser user = new SysUser();
            user.setUsername(username);
            user.setRealname(realname);
            String salt = oConvertUtils.randomGen(8);
            user.setSalt(salt);
            String passwordEncode = PasswordUtil.encrypt(user.getUsername(), password, salt);
            user.setSalt(salt);
            user.setPassword(passwordEncode);
            user.setPhone(phone);
            user.setEmail(email);
            user.setRelTenantIds(tenantId.toString());
            user.setStatus(1);
            user.setDelFlag(CommonConstant.DEL_FLAG_0);
            user.setCreateTime(new Date());
            
            // 获取当前登录用户
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            if (sysUser != null) {
                user.setCreateBy(sysUser.getUsername());
            } else {
                user.setCreateBy("system");
            }
            
            sysUserService.save(user);
            
            // 创建角色
            SysRole role = new SysRole();
            role.setRoleName(roleName);
            role.setRoleCode(roleCode);
            role.setCreateBy(user.getCreateBy());
            role.setCreateTime(new Date());
            role.setDescription("租户ID: " + tenantId);
            role.setTenantId(tenantId);
            sysRoleService.save(role);
            
            // 分配角色给用户
            SysUserRole userRole = new SysUserRole();
            userRole.setUserId(user.getId());
            userRole.setRoleId(role.getId());
            userRole.setTenantId(tenantId);
            sysUserRoleService.save(userRole);
            
            // 分配权限给角色
            if (selectedPermissions != null && selectedPermissions.size() > 0) {
                List<SysRolePermission> rolePermissions = new ArrayList<>();
                for (int i = 0; i < selectedPermissions.size(); i++) {
                    String permissionId = selectedPermissions.getString(i);
                    if (oConvertUtils.isNotEmpty(permissionId)) {
                        SysRolePermission rolePermission = new SysRolePermission();
                        rolePermission.setRoleId(role.getId());
                        rolePermission.setPermissionId(permissionId);
                        rolePermission.setDataRuleIds(null);
                        rolePermissions.add(rolePermission);
                    }
                }
                if (!rolePermissions.isEmpty()) {
                    sysRolePermissionService.saveBatch(rolePermissions);
                }
            }
            
            // 添加系统日志
            baseCommonService.addLog("创建租户管理员，用户名：" + username + "，租户ID：" + tenantId, CommonConstant.LOG_TYPE_2, null);
            
            return Result.OK("租户管理员创建成功");
        } catch (Exception e) {
            log.error("创建租户管理员失败", e);
            return Result.error("创建租户管理员失败: " + e.getMessage());
        }
    }

    /**
     * 获取下一个可用的租户编号
     * @return
     */
    @RequestMapping(value = "/getNextTenantId", method = RequestMethod.GET)
    public Result<Integer> getNextTenantId() {
        Result<Integer> result = new Result<>();
        try {
            // 查询当前最大的租户编号
            QueryWrapper<SysTenant> queryWrapper = new QueryWrapper<>();
            queryWrapper.orderByDesc("id");
            queryWrapper.last("limit 1");
            SysTenant maxTenant = sysTenantService.getOne(queryWrapper);
            
            // 如果没有租户，从1开始，否则在最大值基础上+1
            Integer nextId = maxTenant != null ? maxTenant.getId() + 1 : 1;
            
            result.setSuccess(true);
            result.setResult(nextId);
            result.setMessage("获取成功");
        } catch (Exception e) {
            log.error("获取下一个租户编号出错", e);
            result.setSuccess(false);
            result.setMessage("获取下一个租户编号出错");
        }
        return result;
    }
}
